<template>
  <view class="tn-swiper">
    <!-- 轮播 -->
    <swiper
      class="tn-swiper__swiper"
      :class="[swiperClass]"
      :style="swiperStyle"
      :current="current"
      :interval="interval"
      :circular="circular"
      :vertical="vertical"
      :autoplay="autoplay"
      :duration="duration"
      :previous-margin="handleValueWithUnit(effect3d ? effect3dSpacing : 0)"
      :next-margin="handleValueWithUnit(effect3d ? effect3dSpacing : 0)"
      @change="handleSwiperChange"
    >
      <swiper-item
        v-for="(item, index) in data"
        :key="index"
        class="tn-swiper__swiper-item"
      >
        <view
          class="tn-swiper__item"
          :style="swiperItemStyle(index)"
          @tap.stop="handleClick(index)"
        >
          <!-- 带图片和标题的轮播 -->
          <template v-if="(typeof item !== 'string')">
            <image class="tn-swiper__image" :src="item?.image" :mode="imgMode"></image>
            <view
              v-if="item?.title"
              class="tn-swiper__title tn-text-ellipsis-1"
              :style="titleStyle"
            >
              {{ item.title }}
            </view>
          </template>
          <!-- 只有图片的轮播 -->
          <template v-else>
            <image class="tn-swiper__image" :src="item" :mode="imgMode"></image>
          </template>
        </view>
      </swiper-item>
    </swiper>

    <!-- 指示点 -->
    <view class="tn-swiper__indicator" :style="indicatorStyle">
      <!-- 方形 -->
      <template v-if="indicatorMode === 'rect'">
        <view
          v-for="item in data.length"
          :key="item"
          class="tn-swiper__indicator__rect"
          :class="{'active': currentIndex + 1 === item}"
        ></view>
      </template>
      <!-- 圆角 -->
      <template v-if="indicatorMode === 'round'">
        <view
          v-for="item in data.length"
          :key="item"
          class="tn-swiper__indicator__round"
          :class="{'active': currentIndex + 1 === item}"
        ></view>
      </template>
      <!-- 点 -->
      <template v-if="indicatorMode === 'dot'">
        <view
          v-for="item in data.length"
          :key="item"
          class="tn-swiper__indicator__dot"
          :class="{'active': currentIndex + 1 === item}"
        ></view>
      </template>
      <!-- number序号 -->
      <template v-if="indicatorMode === 'number'">
        <view class="tn-swiper__indicator__number">{{ currentIndex + 1 }}/{{ data.length }}</view>
      </template>
    </view>
  </view>
</template>

<script lang="ts" setup>
import { swiperProps, swiperEmits, SwiperData } from '../../../types/tn-swiper'
import { ColorInfo } from '../../../types/tuniao-ui'
import { computed, CSSProperties, ref } from 'vue'
import useComponentColor from '../../../libs/hooks/useComponentColor'
import { handleValueWithUnit } from '../../../utils'

const props = defineProps(swiperProps)
const emits = defineEmits(swiperEmits)

const { splitColorInfo } = useComponentColor()
// 解析背景颜色
const bgColor = computed<ColorInfo>(() => {
  return splitColorInfo('bg', props?.bgColor || '')
})

// 轮播item数据
const data = computed<SwiperData[] | string[]>(() => {
  return props?.data
})

// swiper样式
const swiperStyle = computed<CSSProperties>(() => {
  let style: CSSProperties = {}
  if (bgColor.value.type === 'style') {
    style.backgroundColor = bgColor.value.value
  }
  if (props?.radius !== 'undefined') {
    style.borderRadius = handleValueWithUnit(props.radius)
  }
  if (props?.height) {
    style.height = handleValueWithUnit(props.height)
  }
  return Object.assign(style, props?.customStyle || {})
})
// 指示器样式
const indicatorStyle = computed<CSSProperties>(() => {
  let style: CSSProperties = {}
  if (props?.indicatorPosition === 'topLeft' || props?.indicatorPosition === 'bottomLeft') style.justifyContent = 'flex-start'
  if (props?.indicatorPosition === 'topCenter' || props?.indicatorPosition === 'bottomCenter') style.justifyContent =  'center'
  if (props?.indicatorPosition === 'topRight' || props?.indicatorPosition === 'bottomRight') style.justifyContent =  'flex-end'
  if (['topLeft','topCenter','topRight'].indexOf(props?.indicatorPosition) >= 0) {
    style.top = '12rpx'
    style.bottom = 'auto'
  } else {
    style.top = 'auto'
    style.bottom = '12rpx'
  }
  style.padding = `0 ${props?.effect3d ? '74rpx' : '24rpx'}`
  return style
})
// 标题样式
const titleStyle = computed<CSSProperties>(() => {
  let style: CSSProperties = {}
  if (!props?.indicatorMode) style.paddingBottom = '12rpx'
  if (!props?.indicatorMode) {
    style.paddingBottom = '12rpx'
  } else {
    if (['bottomLeft','bottomCenter','bottomRight'].indexOf(props?.indicatorPosition) >= 0 && props?.indicatorMode === 'number') {
      style.paddingBottom = '48rpx'
    } else if (['bottomLeft','bottomCenter','bottomRight'].indexOf(props?.indicatorPosition) >= 0 && props?.indicatorMode !== 'number') {
      style.paddingBottom = '40rpx'
    }
  }
  return Object.assign(style, props?.titleStyle || {})
})
// swiper-item样式
const swiperItemStyle = computed<(index: number) => CSSProperties>(() => {
  return (index: number) => {
    let style: CSSProperties = {}
    // 当前index对应的位置标识
    const itemPosition: SwiperItemPosition = checkSwiperItemPosition(index)

    if (props?.radius !== 'undefined') {
      style.borderRadius = handleValueWithUnit(props.radius)
    }
    if (props?.effect3d && itemPosition !== SwiperItemPosition.Current) {
      style.transform = 'scaleY(0.9)'
      style.margin = '0 20rpx'
    }
    // 合并用户自定义对于每个位置的item样式
    Object.assign(style, props?.itemStyle || {})
    if (Object.keys(props?.prevItemStyle).length > 0 && itemPosition === SwiperItemPosition.Prev) {
      Object.assign(style, props.prevItemStyle)
    }
    if (Object.keys(props?.nextItemStyle).length > 0 && itemPosition === SwiperItemPosition.Next) {
      Object.assign(style, props.nextItemStyle)
    }

    return style
  }
})

// swiper对于的类
const swiperClass = computed<string>(() => {
  let clazz: string[] = []
  if (bgColor.value.type === 'class') {
    clazz.push(bgColor.value.value)
  }
  return clazz.join(' ')
})

// 当前显示的item序号
let currentIndex = ref<number>(0)
currentIndex.value = props?.current ? Number(props.current) : 0

// 判断轮播item是什么位置的轮播item
enum SwiperItemPosition {
  Other,
  Prev,
  Current,
  Next
}
const checkSwiperItemPosition = (index: number): SwiperItemPosition => {
  const maxIndex = data.value.length - 1
  if (index === currentIndex.value) {
    return SwiperItemPosition.Current
  }
  if ((currentIndex.value === 0 && index === maxIndex) || index === currentIndex.value - 1) {
    return SwiperItemPosition.Prev
  }
  if ((currentIndex.value === maxIndex && index === 0) || index === currentIndex.value + 1) {
    return SwiperItemPosition.Next
  }
  return SwiperItemPosition.Other
}


// 轮播切换处理
const handleSwiperChange = (e: any) => {
  const current: number = e.detail.current
  currentIndex.value = current
  emits('change', current)
}

// 处理点击事件
const handleClick = (index: number) => {
  emits('click', index)
}
</script>

<script lang="ts">
export default {
  options: {
    // 在微信小程序中将组件节点渲染为虚拟节点，更加接近Vue组件的表现(不会出现shadow节点下再去创建元素)
    virtualHost: true
  }
}
</script>

<style lang="scss" scoped>

.tn-swiper {
  position: relative;
  overflow: hidden;

  &__swiper-item {
    display: flex;
    flex-direction: row;
    align-items: center;
    overflow: hidden;
  }

  &__item {
    position: relative;
    width: 100%;
    height: 100%;
    flex: 1;
    transition: all 0.25s;
    overflow: hidden;
    box-sizing: border-box;
    transform: scaleY(1);
    margin: 0;
    transform-origin: center center;
  }

  &__image {
    width: 100%;
    height: 100%;
    will-change: transform;
    /* #ifdef H5 */
    pointer-events: none;
    /* #endif */
  }

  &__title {
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    width: 100%;
    background-color: rgba(0, 0, 0, 0.2);
    color: rgba(255, 255, 255, 0.8);
    padding: 12rpx 24rpx;
  }

  /* 指示点 start */
  &__indicator {
    position: absolute;
    padding: 0 12rpx;
    display: flex;
    flex-direction: row;
    width: 100%;
    z-index: 1;

    /* rect start */
    &__rect {
      width: 26rpx;
      height: 8rpx;
      background-color: rgba(0, 0, 0, 0.2);
      transition: all 0.25s;
      
      &.active {
        background-color: rgba(255, 255, 255, 0.8);
      }
    }
    /* rect end */

    /* round start */
    &__round {
      width: 12rpx;
      height: 12rpx;
      margin: 0 6rpx;
      border-radius: 20rpx;
      background-color: rgba(0, 0, 0, 0.2);
      transition: all 0.25s;

      &.active {
        width: 34rpx;
        background-color: rgba(255, 255, 255, 0.8);
      }
    }
    /* round end */

    /* dot start */
    &__dot {
      width: 12rpx;
      height: 12rpx;
      margin: 0 6rpx;
      border-radius: 50%;
      background-color: rgba(0, 0, 0, 0.2);
      transition: all 0.25s;

      &.active {
        background-color: rgba(255, 255, 255, 0.8);
      }
    }
    /* dot end */

    /* number start */
    &__number {
      padding: 4rpx 16rpx;
        line-height: 1;
        background-color: rgba(0, 0, 0, 0.3);
        color: rgba(255, 255, 255, 0.8);
        border-radius: 100rpx;
        font-size: 24rpx;
    }
    /* number end */
  }
  /* 指示点 end */
}
</style>
